/*
 * Copyright 2025 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.netflix.graphql.dgs

import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine
import graphql.ExecutionInput
import graphql.execution.preparsed.PreparsedDocumentEntry
import graphql.execution.preparsed.PreparsedDocumentProvider
import java.time.Duration
import java.util.concurrent.CompletableFuture
import java.util.function.Function

class DgsDefaultPreparsedDocumentProvider(
    maximumSize: Long,
    expireAfterAccess: Duration,
) : PreparsedDocumentProvider {
    val cache: Cache<String, PreparsedDocumentEntry> =
        Caffeine
            .newBuilder()
            .maximumSize(maximumSize)
            .expireAfterAccess(expireAfterAccess)
            .build()

    override fun getDocumentAsync(
        executionInput: ExecutionInput,
        parseAndValidateFunction: Function<ExecutionInput, PreparsedDocumentEntry>,
    ): CompletableFuture<PreparsedDocumentEntry> =
        CompletableFuture.completedFuture(
            cache.get(executionInput.query) {
                parseAndValidateFunction.apply(executionInput)
            },
        )
}
